#pragma once

#include "exports.hpp"




namespace Engine
{
	namespace Debugger
	{
		class ENGINE_DEBUGGER_API Event
		{
		public:

			/**
			 * Defines all available kinds of events
			 */
			enum Type
			{
				// Controll Events
				Attach,
				Continue,
				Pause,
				Stop,
				Detach,

				// Data storage events
				SetBreakpoint,

				// Data retrieval events
				GetCallstack,
				GetVariableValue,
			};



			/**
			 * @returns the type of this event
			 */
			virtual Type type() const = 0;

			/**
			 * Serializes this event into the given stream.
			 */
			virtual std::ostream& operator<<(std::ostream& stream) const;

			/**
			 * Deserializes this event from the given stream.
			 *
			 * @throws exception when the event cannot be restored from the stream
			 */
			virtual std::istream& operator>>(std::istream& stream);
		};
		///////////////////////////////////////////////////////////////////////////////////////////




		class ENGINE_DEBUGGER_API AttachEvent
			: public Event
		{
		public:

			typedef void 

			/**
			 * @returns the type of this event
			 */
			virtual Type type() const;
		};
		///////////////////////////////////////////////////////////////////////////////////////////




		class ENGINE_DEBUGGER_API ContinueEvent
			: public Event
		{
		public:

			/**
			 * @returns the type of this event
			 */
			virtual Type type() const;
		};
		///////////////////////////////////////////////////////////////////////////////////////////




		class ENGINE_DEBUGGER_API PauseEvent
			: public Event
		{
		public:

			/**
			 * @returns the type of this event
			 */
			virtual Type type() const;
		};
		///////////////////////////////////////////////////////////////////////////////////////////




		class ENGINE_DEBUGGER_API StopEvent
			: public Event
		{
		public:

			/**
			 * @returns the type of this event
			 */
			virtual Type type() const;
		};
		///////////////////////////////////////////////////////////////////////////////////////////




		class ENGINE_DEBUGGER_API DetachEvent
			: public Event
		{
		public:

			/**
			 * @returns the type of this event
			 */
			virtual Type type() const;
		};
		///////////////////////////////////////////////////////////////////////////////////////////




		class ENGINE_DEBUGGER_API SetBreakpointEvent
			: public Event
		{
		public:

			SetBreakpointEvent();
			SetBreakpointEvent(const std::string& module, const std::string& section, int line, bool set = true);



			/**
			 *@returns the type of this event
			 */
			virtual Type type() const;

			/**
			 * @writes this event into the given stream
			 */
			virtual std::ostream& operator<<(std::ostream& stream) const;

			/**
			 * @reads this event from the given stream
			 */
			virtual std::istream& operator>>(std::istream& stream);

			/**
			 * @returns the module this breakpoint applies to
			 */
			const std::string& module() const;

			/**
			 * @returns the section of code this breakpoint applies to
			 */
			const std::string& section() const;

			/**
			 * @returns the line of the section this breakpoint applies to
			 */
			int line() const;

			/**
			 * Tests if the breakpoint shall be set or unset.
			 */
			bool set() const;

		private:

			std::string   m_module;
			std::string   m_section;
			int           m_line;
			bool          m_set;
		};
		///////////////////////////////////////////////////////////////////////////////////////////




		class ENGINE_DEBUGGER_API GetCallstackEvent
			: public Event
		{
		public:

			/**
			 * @returns the type of this event
			 */
			virtual Type type() const;
		};
		///////////////////////////////////////////////////////////////////////////////////////////
	}
	///////////////////////////////////////////////////////////////////////////////////////////////
}
///////////////////////////////////////////////////////////////////////////////////////////////////
